//
// Created by dave on 18-7-29.
//

#pragma once
#include <string>
#include <algorithm>
#include "encodable.h"
#include "msg_body.h"
#include "data_utils.h"

class DataPack : public Encodable {
public:
    std::vector<char> encode() override {
        std::vector<char> bb = body_->encode();
        std::vector<char> ret;
        ret.reserve(bb.size() + 20);
        write_word(ret, msgId_);
        write_word(ret, static_cast<unsigned short>(bb.size())); // 消息包封装项，这里假定不分包，数据不加密
        write_bcd(ret, sim_);
        write_word(ret, seqNo_);
        for_each(bb.cbegin(), bb.cend(), [&ret](char val) {
            ret.push_back(val);
        });
        ret.push_back(::checksum(ret));

        // 转义
        std::vector<char> escaped;
        escaped.reserve(ret.size() + 50);
        escaped.push_back(0x7E);
        for_each(ret.cbegin(), ret.cend(), [&escaped](char val) {
            if (val == 0x7D) {
                escaped.push_back(0x7D);
                escaped.push_back(0x01);
            } else if (val == 0x7E) {
                escaped.push_back(0x7D);
                escaped.push_back(0x02);
            } else {
                escaped.push_back(val);
            }
        });
        escaped.push_back(0x7E); //标识位(0x7E)
        return escaped;
    }

    unsigned short getMsgId() { return msgId_; }
    void setMsgId(unsigned short msgId) { this->msgId_ = msgId; }

    std::string getSim() { return sim_; }
    void setSim(std::string sim) { this->sim_ = sim; }

    unsigned short getSeqNo() { return seqNo_; }
    void setSeqNo(unsigned short seqNo) { this->seqNo_ = seqNo; }

    bool isEncrypted() { return encrypted_; }
    void setEncrypted(bool encrypted) { this->encrypted_ = encrypted; }

    bool isSplit() { return split_; }
    void setSplit(bool split) { this->split_ = split; }

    unsigned short getContentSize() { return contentSize_; }
    void setContentSize(unsigned short content_size) { this->contentSize_ = content_size; }

    unsigned short getPkgCount() { return pkgCount_; }
    void setPkgCount(unsigned short pkgCount) { this->pkgCount_ = pkgCount; }

    unsigned short getPkgNo() { return pkgNo_; }
    void setPkgNo(unsigned short pkg_no) { this->pkgNo_ = pkg_no; }

    char getChecksum() { return checksum_; }
    void setChecksum(char checksum) { this->checksum_ = checksum; }

    std::shared_ptr<MsgBody> getBody() { return body_; }
    void setBody(std::shared_ptr<MsgBody> body) { this->body_ = body; }

private:
    /// 消息ID
    unsigned short msgId_;
    /// 手机号
    std::string sim_;
    /// 流水号
    unsigned short seqNo_;
    /// 是否加密
    bool encrypted_;
    /// 是否分包
    bool split_;
    /// 消息体长度
    unsigned short contentSize_;
    /// 分包后的包数，未分包时为0
    unsigned short pkgCount_ = 0;
    /// 包序号，示分包时为0
    unsigned short pkgNo_ = 0;
    /// 校验码
    char checksum_;
    /// 消息体
    std::shared_ptr<MsgBody> body_;
};

